package com.hockeo.server.rpc.classic;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.hockeo.client.VHMain;
import com.hockeo.client.model.JSData;
import com.hockeo.client.model.LoginStatus;
import com.hockeo.server.data.DAO;
import com.hockeo.server.data.entity.Association;
import com.hockeo.server.servlet.convert.Gwt2JConverter;
import com.hockeo.server.servlet.convert.GwtConverterFactory;
import com.hockeo.server.servlet.convert.GwtEnabled;
import com.hockeo.shared.VHUtil;
import com.hockeo.shared.domain.persistent.Manager;
import com.hockeo.shared.rpc.classic.IRpcClassicService;
import com.hockeo.shared.rpc.classic.RpcVoidResult;
import com.hockeo.tinygds.TKey;
import com.hockeo.tinygds.TQuery;
import com.hockeo.tinygds.TinyGDS;

/**
 * Implementation of the classic GWT/RPC remote service.
 *
 * @version $Id$
 * @author jjanke
 */
public class RpcClassicServiceImpl extends RpcBaseServlet implements IRpcClassicService
{
  private static final long serialVersionUID = 1L;

  @Override
  public RpcVoidResult commitData( List<JSData> list )
  {
    Gwt2JConverter converter = new GwtConverterFactory().getGwt2JConverter();
    TinyGDS tgds = DAO.get().begin();

    for ( JSData src : list )
    {
      GwtEnabled dest = converter.convert( src );

      switch ( src.getChangeType() )
      {
        case UNCHANGED:
          break;

        case NEW:
        case MODIFIED:
          tgds.put( dest );
          break;

        case DELETED:
          tgds.delete( dest );
          break;

        default:
          throw new IllegalStateException( "Unexpected ChangeType " + src.getChangeType().name() );
      }
    }

    return RpcVoidResult.VOID;
  }

  @Override
  public LoginStatus getLoginStatus()
  {
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();

    LoginStatus loginStatus;

    if ( user != null )
    {
      loginStatus = new LoginStatus( user.getNickname(), Boolean.valueOf( userService.isUserAdmin() ),
          userService.createLogoutURL( VHMain.URL_MAIN_PAGE ) );

      // if the user does not yet exist in the database, create it
      //
      TinyGDS tgds = DAO.get().begin();
      Manager manager = tgds.find( new TKey<Manager>( Manager.class, user.getUserId() ) );
      HttpServletRequest rq = getThreadLocalRequest();

      if ( manager == null )
        manager = new Manager( user.getUserId(), user.getEmail(), rq.getRemoteAddr(), rq.getLocalName() );
      else
        manager.update( user.getEmail(), rq.getRemoteAddr(), rq.getLocalName() );

      tgds.put( manager );
    }
    else
      loginStatus = new LoginStatus( null, Boolean.FALSE, userService.createLoginURL( VHUtil.URL_WELCOME_PAGE ) );

    return loginStatus;
  }

  @Override
  public List<JSData> getAllAssociations()
  {
    TinyGDS tgds = DAO.get().begin();
    TQuery<Association> query = tgds.query( Association.class );

    query.offset( 0 );

    return new GwtConverterFactory().getJ2GwtConverter().convert( query.asList() );
  }
}
